package com.cugmarket.controller.upload;
import com.cugmarket.constant.MessageConstant;
import com.cugmarket.dto.Result;
import com.cugmarket.exception.BaseException;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/user/upload")
@Slf4j
public class FileUploadController {

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucket-name}")
    private String bucketName;

    /**
     * 上传文件到 MinIO
     * @param files
     * @return
     */
    @PostMapping()
    public Result uploadFiles(@RequestBody MultipartFile[] files) {
        log.info("访问到文件上传接口");
        List<String> fileUrls = new ArrayList<>();
        try {
            // 遍历每个文件并上传
            for (MultipartFile file : files) {
                // 1. 获取文件名后缀
                String originalFilename = file.getOriginalFilename();
                String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
                // 获取唯一文件名，防止文件名重复
                String fileName = UUID.randomUUID() + extension;
                // 获取文件流
                InputStream inputStream = file.getInputStream();
                // 上传文件到 MinIO
                minioClient.putObject(
                        PutObjectArgs.builder()
                                .bucket(bucketName)
                                .object(fileName)
                                .stream(inputStream, file.getSize(), -1)
                                .contentType(file.getContentType())
                                .build()
                );

                // 获取文件访问路径并保存
                String url = minioClient.getPresignedObjectUrl(
                        GetPresignedObjectUrlArgs.builder()
                                .bucket(bucketName)
                                .object(fileName)
                                .method(Method.GET)
                                .build()
                );
                url = url.substring(0, url.indexOf('?'));
                fileUrls.add(url); // 添加文件的 URL
            }
            return Result.success(fileUrls); // 返回所有上传文件的访问 URL 列表

        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BaseException(e.getMessage());
        }
    }

    /**
     * 删除 MinIO 中的多个文件
     * @param fileNames 文件名列表
     * @return
     */
    @DeleteMapping()
    public Result deleteFiles(@RequestBody List<String> fileNames) {
        log.info("访问到文件删除接口",fileNames);
        try {
            // 遍历文件名列表并删除每个文件
            for (String fileName : fileNames) {
                minioClient.removeObject(
                        RemoveObjectArgs.builder()
                                .bucket(bucketName)
                                .object(fileName)
                                .build()
                );
                log.debug("文件删除成功: " + fileName);
            }
            return Result.success(MessageConstant.DELETE_SUCCESS);

        } catch (Exception e) {
            log.error("MiniO文件删除失败: " + e.getMessage());
            throw new BaseException(e.getMessage());
        }
    }


    /**
     * 查询 MinIO 桶中的所有文件名
     * @return
     */
    @GetMapping("/list")
    public Result listFiles() {
        try {
            List<String> fileNames = new ArrayList<>();
            // 使用 MinIO 的 listObjects 列出所有文件
            Iterable<io.minio.Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
            for (io.minio.Result<Item> item : results) {
                fileNames.add(item.get().objectName());
            }
            return Result.success(fileNames); // 返回文件名列表

        } catch (Exception e) {
            log.error("查询文件列表失败: " + e.getMessage());
            throw new BaseException(e.getMessage());
        }
    }

}
